import re
from typing import List
from moviepy import TextClip
from config import config


def srt_time_to_seconds(time_str: str) -> float:
    time_part, ms_part = time_str.split(",")
    h, m, s = map(int, time_part.split(":"))
    ms = int(ms_part)
    return h * 3600 + m * 60 + s + ms / 1000.0


def seconds_to_srt_time(seconds: float) -> str:
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)
    milliseconds = int((seconds % 1) * 1000)
    return f"{hours:02d}:{minutes:02d}:{secs:02d},{milliseconds:03d}"


def generate_srt_content(text: str, duration: float) -> str:
    if not text.strip():
        return ""

    sentences = re.split(r"[.!?。！？；：]+", text)
    sentences = [s.strip() for s in sentences if s.strip()]

    segments = []
    current_segment = ""

    for sentence in sentences:
        sentence = sentence.strip()
        if not sentence:
            continue

        if not current_segment:
            current_segment = sentence
        elif len(current_segment) + len("。" + sentence) <= config.subtitle.max_chars_per_segment:
            current_segment += "。" + sentence
        else:
            segments.append(current_segment)
            current_segment = sentence

    if current_segment:
        segments.append(current_segment)

    final_segments = []
    for segment in segments:
        if len(segment) > config.subtitle.max_chars_per_segment:
            words = segment.split()
            temp_segment = ""

            for word in words:
                if not temp_segment:
                    temp_segment = word
                elif len(temp_segment) + len(" " + word) <= config.subtitle.max_chars_per_segment:
                    temp_segment += " " + word
                else:
                    final_segments.append(temp_segment)
                    temp_segment = word

            if temp_segment:
                final_segments.append(temp_segment)
        else:
            final_segments.append(segment)

    segments = final_segments
    total_segments = len(segments)
    if total_segments == 0:
        return ""

    total_chars = sum(len(segment) for segment in segments)
    srt_content = ""
    current_time = 0.0

    for i, segment in enumerate(segments):
        char_ratio = (
            len(segment) / total_chars if total_chars > 0 else 1.0 / total_segments
        )
        segment_duration = duration * char_ratio
        segment_duration = max(config.subtitle.min_duration, min(segment_duration, config.subtitle.max_duration))

        start_time = current_time
        end_time = current_time + segment_duration

        if i == total_segments - 1:
            end_time = duration

        current_time = end_time

        start_time_str = seconds_to_srt_time(start_time)
        end_time_str = seconds_to_srt_time(end_time)

        srt_content += f"{i + 1}\n"
        srt_content += f"{start_time_str} --> {end_time_str}\n"
        srt_content += f"{segment}\n\n"

    return srt_content


def generate_combined_srt(paragraphs: List[str], video_clips) -> str:
    combined_srt = ""
    current_time_offset = 0.0
    subtitle_index = 1

    for i, (paragraph, clip) in enumerate(zip(paragraphs, video_clips)):
        segment_duration = clip.duration
        segment_srt = generate_srt_content(paragraph, segment_duration)

        if not segment_srt.strip():
            current_time_offset += segment_duration
            continue

        entries = segment_srt.strip().split("\n\n")

        for entry in entries:
            if not entry.strip():
                continue

            lines = entry.strip().split("\n")
            if len(lines) < 3:
                continue

            time_line = lines[1]
            if "-->" not in time_line:
                continue

            start_time_str, end_time_str = time_line.split(" --> ")
            start_time = srt_time_to_seconds(start_time_str.strip()) + current_time_offset
            end_time = srt_time_to_seconds(end_time_str.strip()) + current_time_offset

            subtitle_text = "\n".join(lines[2:])

            combined_srt += f"{subtitle_index}\n"
            combined_srt += f"{seconds_to_srt_time(start_time)} --> {seconds_to_srt_time(end_time)}\n"
            combined_srt += f"{subtitle_text}\n\n"

            subtitle_index += 1

        current_time_offset += segment_duration
        print(f"段落 {i+1} 时长: {segment_duration:.2f}秒，累计时长: {current_time_offset:.2f}秒")

    return combined_srt


def generate_combined_srt_fast(paragraphs: List[str], video_segments: List[str]) -> str:
    """
    快速生成合并SRT字幕文件，无需依赖MoviePy clips
    通过读取视频文件元数据获取时长
    """
    import subprocess
    combined_srt = ""
    current_time_offset = 0.0
    subtitle_index = 1

    for i, (paragraph, video_path) in enumerate(zip(paragraphs, video_segments)):
        try:
            # 使用ffprobe获取视频时长
            cmd = [
                'ffprobe', '-v', 'quiet', '-show_entries', 'format=duration',
                '-of', 'default=noprint_wrappers=1:nokey=1', video_path
            ]
            result = subprocess.run(cmd, capture_output=True, text=True, check=True)
            segment_duration = float(result.stdout.strip())
        except (subprocess.CalledProcessError, ValueError):
            # 回退方案：估算时长（按每秒2.5个字符）
            segment_duration = max(len(paragraph) / 2.5, 3.0)
        
        segment_srt = generate_srt_content(paragraph, segment_duration)

        if not segment_srt.strip():
            current_time_offset += segment_duration
            continue

        entries = segment_srt.strip().split("\n\n")

        for entry in entries:
            if not entry.strip():
                continue

            lines = entry.strip().split("\n")
            if len(lines) < 3:
                continue

            time_line = lines[1]
            if "-->" not in time_line:
                continue

            start_time_str, end_time_str = time_line.split(" --> ")
            start_time = srt_time_to_seconds(start_time_str.strip()) + current_time_offset
            end_time = srt_time_to_seconds(end_time_str.strip()) + current_time_offset

            subtitle_text = "\n".join(lines[2:])

            combined_srt += f"{subtitle_index}\n"
            combined_srt += f"{seconds_to_srt_time(start_time)} --> {seconds_to_srt_time(end_time)}\n"
            combined_srt += f"{subtitle_text}\n\n"

            subtitle_index += 1

        current_time_offset += segment_duration
        print(f"段落 {i+1} 时长: {segment_duration:.2f}秒，累计时长: {current_time_offset:.2f}秒")

    return combined_srt


def create_subtitle_clips_from_srt(srt_content: str, video_size: tuple) -> list:
    if not srt_content.strip():
        return []

    subtitle_clips = []
    entries = re.split(r"\n\s*\n", srt_content.strip())

    for entry in entries:
        lines = entry.strip().split("\n")
        if len(lines) < 3:
            continue

        time_line = lines[1]

        if "-->" not in time_line:
            continue

        start_time_str, end_time_str = time_line.split(" --> ")
        start_time = srt_time_to_seconds(start_time_str.strip())
        end_time = srt_time_to_seconds(end_time_str.strip())
        duration = end_time - start_time

        subtitle_text = "\n".join(lines[2:])

        if not subtitle_text.strip():
            continue

        subtitle_clip = (
            TextClip(
                text=subtitle_text,
                font_size=config.subtitle.font_size,
                color="white",
                stroke_color="black",
                stroke_width=config.subtitle.stroke_width,
                method="caption",
                size=(video_size[0] - config.subtitle.margin_horizontal, None),
            )
            .with_position(("center", video_size[1] - config.subtitle.margin_bottom))
            .with_start(start_time)
            .with_duration(duration)
        )

        subtitle_clips.append(subtitle_clip)

    print(f"从SRT生成了 {len(subtitle_clips)} 个字幕片段")
    return subtitle_clips